#pragma once
#include <cstdlib>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <sys/wait.h>
#include <functional>
#include "Common.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"
namespace wxd
{
    const int default_sockfd = -1;
    const int default_listen_num = 8;
    //using task_t = std::function<void()>;
    using func_t = std::function<std::string(const std::string&)>;
    class TcpServer : public nocopy // 继承禁止拷贝
    {
    private:
        // 服务器默认处理方法 Echo
        std::string Echo(const std::string &msg)
        {
            return msg;
        }
        // TcpServer提供通信服务的接口
        void Service(int sockfd, const InetAddrTrans &peer_trans) // 把用户信息也带进来
        {
            while (true)
            {
                // 读取消息
                char read_buffer[1024];
                ssize_t size = read(sockfd, read_buffer, sizeof(read_buffer) - 1);
                if (size > 0)
                {
                    // 读取成功
                    read_buffer[size] = 0;
                    LOG(LogLevel::INFO) << "recv:[" << peer_trans.Ip() << ":" << peer_trans.Port() << "]" << read_buffer;
                    // echo
                    std::string send_msg = _func(read_buffer);
                    // 发送消息
                    ssize_t wsize = write(sockfd, send_msg.c_str(), send_msg.size());
                    if (wsize < 0)
                    {
                        LOG(LogLevel::WARNING) << "发送异常！";
                        break;
                    }
                }
              
                else
                {
                    // 读取异常
                    LOG(LogLevel::WARNING) << "读取异常！";
                    break;
                }
            }

            // 服务完毕关闭sockfd
            close(sockfd);
        }

        // 线程的Routine
        static void Routine(TcpServer *self, int sockfd, InetAddrTrans peer_trans)
        {
            // detach
            pthread_detach(pthread_self());
            // 提供服务
            self->Service(sockfd, peer_trans);
        }
        class ThreadData
        {
        public:
            ThreadData(TcpServer* server_ptr,int sockfd,const InetAddrTrans&addr_trans)
            :_tcp_server_ptr(server_ptr)
            ,_sockfd(sockfd)
            ,_addr_trans(addr_trans)
            {}
            TcpServer *_tcp_server_ptr;
            int _sockfd;
            InetAddrTrans _addr_trans;
        };
        static void *Routine(void *args)
        {
            //detach
            pthread_detach(pthread_self());
            //原生线程库回调方法
            ThreadData* ptd = static_cast<ThreadData*>(args);
            //提供服务
            ptd->_tcp_server_ptr->Service(ptd->_sockfd,ptd->_addr_trans);
            delete ptd;
            return nullptr;
        }

    public:
        TcpServer(uint16_t port,func_t func)
            : _port(port), _listen_sockfd(default_sockfd)
            ,_func (func)
        {
        }

        // 服务器的初始化
        void Init()
        {
            // 创建套接字
            _listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
            if (_listen_sockfd < 0)
            {
                LOG(LogLevel::FATAL) << "create socket fail！";
                exit(SOCKET_ERR);
            }
            LOG(LogLevel::INFO) << "create socket success！" << " sockfd: " << _listen_sockfd;
            // 绑定信息至套接字
            InetAddrTrans addr_trans(_port);
            int n = bind(_listen_sockfd, addr_trans.SockaddrPtr(), addr_trans.SockLen());
            if (n < 0)
            {
                LOG(LogLevel::FATAL) << "bind fail！";
                exit(BIND_ERR);
            }
            LOG(LogLevel::INFO) << "bind success！" << " sockfd: " << _listen_sockfd;
        }

        void Start()
        {
            while (true)
            {
                // 监听
                int n = listen(_listen_sockfd, default_listen_num);
                if (n < 0)
                {
                    LOG(LogLevel::FATAL) << "listen fail！";
                    exit(LISTEN_ERR);
                }
                LOG(LogLevel::INFO) << "listening fd:" << _listen_sockfd;

                sockaddr_in peer;
                socklen_t len = sizeof(peer);
                memset(&peer, 0, len);

                // 获取连接
                int sockfd = accept(_listen_sockfd, ADDR_PTR(peer), &len);
                if (sockfd < 0)
                {
                    LOG(LogLevel::WARNING) << "accept fail！";
                    continue;
                }
                InetAddrTrans peer_trans(peer);
                // 获取连接成功，打印连接者信息
                LOG(LogLevel::INFO) << "accept success :" << "[" << peer_trans.Ip() << ":" << peer_trans.Port() << "]";

                 // 多线程版本-原生线程库
                // 创建新线程
                pthread_t tid;
                ThreadData* ptd = new ThreadData(this,sockfd,peer_trans);
                pthread_create(&tid, nullptr, Routine, ptd);
            }
        }

    private:
        u_int16_t _port;    // 记录服务器的端口号
        int _listen_sockfd; // 记录服务器的套接字

        func_t _func;//接收外部传来的方法
    };
}